const axios = require('axios');
const AIDao = require('../database/AIDao');
const UserDao = require('../database/UserDao');

class AIController {
    constructor(pool) {
        this.pool = pool;
        this.aiDao = new AIDao(pool);
        this.userDao = new UserDao(pool);
    }

    funList = {"政府收购":"getGovBuy","政府出售":"getGovSell","经销商收购":"dealerBuy","农户出售":"farmerSell","我的订单":"getMyOrders"};
    identity = {"farmer": "农户","dealer": "经销商","gov":"政府"}

    async funCall(question,side_info,user_id) {
        try {
            let systemPrompt = `你是一个function calling识别专家，你可以结合用户身份信息从用户的问题中识别出需要调用的函数，并且只去做这个函数识别任务。
            可调用的函数列表如下: ${this.funList}，
            用户补充身份信息如下: ${side_info}，
            请你理解后只返回函数列表中对应的键值对，如果没有对应的函数则返回空对象，不做除了函数识别任务以外的其他任何内容。
            例如：
            用户输入: "截止目前，政府有在收购哪些农产品"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy"}\`\`\`"
            
            用户输入: "有哪些农产品在收购"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy","经销商收购":"dealerBuy"}\`\`\`"
            
            用户输入: "我有不少苹果，我可以出售给谁"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy","经销商收购":"dealerBuy"}\`\`\`"
            
            用户输入: "我需要不少香蕉，有香蕉卖吗，价格如何"
            你的回答: "\`\`\`json{"政府出售":"getGovSell","农户出售":"farmerSell"}\`\`\`"
            
            用户输入: "推荐一种平台里卖的这个时间段的应季水果，并提供联系方式"
            你的回答: "\`\`\`json{"政府出售":"getGovSell","农户出售":"farmerSell"}\`\`\`"

            用户输入: "我有哪些订单记录"
            你的回答: "\`\`\`json{"我的订单":"getMyOrders"}\`\`\`"
            
            用户输入: "我想知道我最近买的农产品有哪些"
            你的回答: "\`\`\`json{"我的订单":"getMyOrders"}\`\`\`"
            
            用户输入: "现在市场上有什么新鲜蔬菜可以购买"
            你的回答: "\`\`\`json{"政府出售":"getGovSell","农户出售":"farmerSell"}\`\`\`"
            
            用户输入: "我是农户，想了解哪些经销商在收购玉米"
            你的回答: "\`\`\`json{"经销商收购":"dealerBuy"}\`\`\`"
            
            用户输入: "最近有什么农产品价格比较好，我想卖一些"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy","经销商收购":"dealerBuy"}\`\`\`"
            
            用户输入: "我想查看我之前的交易记录"
            你的回答: "\`\`\`json{"我的订单":"getMyOrders"}\`\`\`"
            
            用户输入: "政府最近在收购什么农产品，价格如何"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy"}\`\`\`"
            
            用户输入: "我想了解一下现在农户们都在卖什么水果"
            你的回答: "\`\`\`json{"农户出售":"farmerSell"}\`\`\`"

            用户输入: "我家地里的蔬菜成熟了，想找个好价格卖出去"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy","经销商收购":"dealerBuy"}\`\`\`"
            
            用户输入: "最近想买点新鲜的水果，哪里有卖的"
            你的回答: "\`\`\`json{"政府出售":"getGovSell","农户出售":"farmerSell"}\`\`\`"
            
            用户输入: "我上个月卖出去的那批苹果，收到货款了吗"
            你的回答: "\`\`\`json{"我的订单":"getMyOrders"}\`\`\`"
            
            用户输入: "想了解一下最近的市场行情"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy","政府出售":"getGovSell","经销商收购":"dealerBuy","农户出售":"farmerSell"}\`\`\`"
            
            用户输入: "我想看看我之前的购买记录"
            你的回答: "\`\`\`json{"我的订单":"getMyOrders"}\`\`\`"
            
            用户输入: "有什么渠道可以卖掉我的农产品"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy","经销商收购":"dealerBuy"}\`\`\`"
            
            用户输入: "我想知道哪里可以买到优质的蔬菜"
            你的回答: "\`\`\`json{"政府出售":"getGovSell","农户出售":"farmerSell"}\`\`\`"

            用户输入: "我有出售什么农产品吗"
            你的回答: "\`\`\`json{"政府出售":"getGovSell","农户出售":"farmerSell"}\`\`\`"

            用户输入: "我有收购什么农产品吗"
            你的回答: "\`\`\`json{"政府收购":"getGovBuy","经销商收购":"dealerBuy"}\`\`\`"

            用户输入: "我出售的农产品现在卖的咋样了"
            你的回答: "\`\`\`json{"政府出售":"getGovSell","农户出售":"farmerSell"}\`\`\`"
            `
            let messages = [{ role: 'system', content: systemPrompt }];
            messages = messages.concat(question)
            // 使用循环尝试最多3次获取有效的意图对象
            let intentObj = null;
            let maxAttempts = 3;
            let currentAttempt = 0;
            
            while (currentAttempt < maxAttempts) {
                currentAttempt++;
                console.log(`尝试第 ${currentAttempt} 次获取意图...`);
                
                try {
                    // 调用DeepSeek API以确认用户意图
                    const response = await axios.post(
                        'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions',
                        {
                            model: 'deepseek-v3',
                            messages: messages,
                            // max_tokens: 4096,
                        },
                        {
                            headers: {
                                'Content-Type': 'application/json',
                                'Authorization': 'Bearer sk-893ad79db95a4414ade4fd5f6e6605fa' // API密钥
                            }
                        }
                    );

                    // 从模型响应中提取意图
                    const intent = response.data.choices[0].message.content.trim();
                    // console.log(intent);
                    
                    // 解析JSON字符串
                    try {
                        // 使用正则表达式提取JSON部分
                        const jsonMatch = intent.match(/```json(.*?)```/s);
                        if (jsonMatch && jsonMatch[1]) {
                            // 提取JSON字符串并解析
                            const jsonStr = jsonMatch[1].trim();
                            intentObj = JSON.parse(jsonStr);
                            console.log("解析后的意图对象:", intentObj);
                        } else {
                            // 如果没有匹配到```json```格式，尝试直接解析
                            const jsonStr = intent.replace(/```/g, '').trim();
                            intentObj = JSON.parse(jsonStr);
                            console.log("直接解析的意图对象:", intentObj);
                        }
                    } catch (error) {
                        console.log("解析JSON失败");
                        intentObj = null; // 设置为null以便重试
                    }

                    // 检测并清理不在funList中的键值对
                    if (intentObj) {
                        const validIntentObj = {};
                        for (const [key, value] of Object.entries(intentObj)) {
                            if (Object.values(this.funList).includes(value) && Object.keys(this.funList).includes(key)) {
                                validIntentObj[key] = value;
                            } else {
                                console.log(`移除无效的函数调用: ${key} -> ${value}`);
                            }
                        }
                        intentObj = validIntentObj;
                    }
                    
                    // 如果获取到有效的意图对象（不为空），则跳出循环
                    if (intentObj && Object.keys(intentObj).length > 0) {
                        console.log(`第 ${currentAttempt} 次尝试成功获取到意图对象`);
                        break;
                    } else {
                        console.log(`第 ${currentAttempt} 次尝试未获取到有效意图对象，将重试...`);
                    }
                    
                } catch (error) {
                    console.error(`第 ${currentAttempt} 次调用DeepSeek API出错:`, error.response?.data || error.message);
                }
            }

            // 如果所有尝试后仍未获取到有效意图对象，则使用所有函数
            if (!intentObj || Object.keys(intentObj).length === 0) {
                console.log(`经过 ${maxAttempts} 次尝试后仍未获取到有效意图对象，将执行所有函数`);
                intentObj = this.funList;
            }

            // 根据识别的意图去调用函数获取数据
            let dataResults = {};
            for (const [key, functionName] of Object.entries(intentObj)) {
                if (typeof this[functionName] === 'function') {
                    try {
                        // 只有getMyOrders需要user_id参数，其他函数不需要
                        if (functionName === 'getMyOrders') {
                            dataResults[key] = await this[functionName](user_id);
                        } else {
                            dataResults[key] = await this[functionName]();
                        }
                    } catch (error) {
                        console.error(`调用函数 ${functionName} 出错:`, error);
                        dataResults[key] = `调用函数 ${functionName} 出错`;
                    }
                } else {
                    console.error(`函数 ${functionName} 不存在`);
                    dataResults[key] = {}; // 返回空对象作为兜底
                }
            }
            let resultString = '';
            for (const [key, value] of Object.entries(dataResults)) {
                resultString += `${key}:\n${value}\n\n`;
            }
            // console.log(resultString);
            return resultString.trim(); // 去除末尾多余的换行符
            
        } catch (error) {
            console.error('调用DeepSeek API出错:', error.response?.data || error.message);
        }
    }

    // 流式DeepSeek API代理接口
    async streamChatWithAI(req, res) {
        try {
            const { messages, model, type } = req.body;
            var user_id = req.user?.userId || 1;
            // 设置响应头，支持流式传输
            res.setHeader('Content-Type', 'text/event-stream');
            res.setHeader('Cache-Control', 'no-cache');
            res.setHeader('Connection', 'keep-alive');
            // console.log(messages)
            var systemPrompt = "";
            var lastQue;
            // 获取东8区时间
            var timestamp = new Date(new Date().getTime() + 8 * 60 * 60 * 1000).toISOString().slice(0, 19).replace('T',' ');
            const {user_name,user_address,role_name,nick_name} = await this.userDao.getUserInfo(user_id);
            var side_info = `系统中有当前用户的以下补充信息: 当前时间${timestamp}, 用户的ID: ${user_id}, 用户名: ${user_name}, 用户的身份: ${this.identity[role_name]}, 用户的名称: ${nick_name}, 用户的地址: ${user_address}
                            你需要结合这些用户数据回答用户问题，比如对比数据库农产品数据的ID和可以确定哪些是该用户发布的，但要注意，回答的时候不要出现的用户ID。`
            // console.log(`补充信息: ${side_info}`)
            console.log(`咨询类型：${type}`);
            if(type=="agri-data"){
                systemPrompt = `你是一个名为AgriHub的农产品集散平台的数据咨询客服，提供给你相关的农产品数据，根据数据回答用户关于农产品的相关问题，请以合理美观的markdown格式回答用户问题，不出现突兀的样式，对于其它问题以委婉的语气拒绝。
                ${side_info}`

                // 数据查询，自定义function calling
                const dbData = await this.funCall(messages, side_info,user_id)
                lastQue = messages.pop();
                if(!(Object.keys(dbData).length === 0)){
                    // console.log(`数据库数据: ${dbData}`)
                    let productData = dbData;
                    // console.log(productData)
                    let datas = {role: "assistant",content:`这是从数据库中获取的相关数据:\n ${productData},\n我要结合这些数据为用户解答问题。`};
                    messages.push(datas);
                }
            }else{
                lastQue = messages.pop();
                systemPrompt = `你是一个名为AgriHub的农产品集散平台里的农业专家，请根据专业知识回答农业相关问题。你是面向普通农户，请用简单易懂的语言回答，必要时可以举例说明。请以合理美观的markdown格式回答用户问题，不出现突兀的样式。
                ${side_info}`
            }
            
            messages.unshift({role:"system",content:systemPrompt});
            messages.push(lastQue);
            // 创建到DeepSeek API的请求
            const response = await axios({
                method: 'post',
                url: 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions',
                data: {
                    model: model || 'deepseek-v3',
                    messages: messages,
                    stream: true
                },
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer sk-893ad79db95a4414ade4fd5f6e6605fa' // API密钥
                },
                responseType: 'stream'
            });

            let fullResponse = ''; // 用于存储完整响应
            // 将DeepSeek的流式响应转发给前端
            response.data.on('data', (chunk) => {
                const chunkStr = chunk.toString();
                // 将数据按换行符分割，处理可能的多行数据，第一次响应有两块data
                const lines = chunkStr.split('\n');
                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const jsonStr = line.slice(6).trim();
                        if (jsonStr && jsonStr !== '[DONE]') {
                            try {
                                const jsonData = JSON.parse(jsonStr);
                                fullResponse += jsonData.choices[0].delta.content;
                                // 这里可以处理实际的内容
                            } catch (e) {
                                console.error('解析JSON失败:', e);
                            }
                        }
                    }
                }
                res.write(chunkStr);
            });
            
            response.data.on('end', async () => {
                // console.log('完整回答:', fullResponse);
                
                // 保存AI交互记录到数据库
                try {
                    const result = await this.aiDao.saveInteraction(
                        user_id,
                        type,
                        lastQue.content,
                        fullResponse,
                    );
                    
                    if (result.success) {
                        console.log('AI交互记录已保存:', result.data.interaction_id);
                    } else {
                        console.error('保存AI交互记录失败:', result.error);
                    }
                } catch (error) {
                    console.error('保存AI交互记录时发生错误:', error);
                }
                
                res.end();
            });
            
            // 处理客户端断开连接
            req.on('close', () => {
                response.data.destroy();
            });
            
        } catch (error) {
            console.error('调用DeepSeek API出错:', error.response?.data || error.message);
            res.write(`data: ${JSON.stringify({ error: '服务器错误', message: error.message })}\n\n`);
            res.end();
        }
    }

    // 获取历史记录，并按将question和response组装成问答对，然后按时间顺序拼接成数组返回
    async getHistoryMsg(interaction_type, user_id) {
        try {
            // 默认用户ID为1，如果传入了用户ID则使用传入的值
            user_id = user_id || 1;
            
            // 调用AIDao获取历史交互记录，限制10条
            const result = await this.aiDao.getUserInteractions(user_id, interaction_type, 10);
            
            if (!result.success) {
                return {
                    success: false,
                    error: result.error
                };
            }
            
            // 将数据库记录转换为前端需要的格式 [{ role: 'user', content: '...' }, { role: 'assistant', content: '...' }]
            const messages = [];
            result.data.forEach(record => {
                // 添加用户问题
                messages.push({
                    role: 'user',
                    content: record.question
                });
                
                // 添加AI回答
                messages.push({
                    role: 'assistant',
                    content: record.response
                });
            });

            return messages;
        } catch (error) {
            console.error('获取历史消息失败:', error);
            return [];
        }
    }

    async getHistoryMsgApi(req, res){
        const { type } = req.query;
        // 从req.user中获取user_id，如果不存在则默认为1
        let user_id = req.user?.userId || 1;
        // 调用getHistoryMsg方法获取历史消息，使用await确保异步操作完成
        const messages = await this.getHistoryMsg(type, user_id);
        
        // 将结果返回给客户端
        res.json(messages);
    }

    /**
     * 清空AI历史记录
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     */
    async clearHistoryMsgApi(req, res) {
        try {
            const { type } = req.body;
            let user_id = req.user?.userId || 1;

            // 调用AIDao的clearUserInteractions方法清空历史记录
            const result = await this.aiDao.clearUserInteractions(user_id, type);

            if (result.success) {
                res.json({
                    success: true,
                    message: '历史记录已清空',
                    affectedRows: result.data.affectedRows
                });
            } else {
                res.status(500).json({
                    success: false,
                    message: '清空历史记录失败',
                    error: result.error
                });
            }
        } catch (error) {
            console.error('清空历史记录时发生错误:', error);
            res.status(500).json({
                success: false,
                message: '服务器错误',
                error: error.message
            });
        }
    }

    // 获取政府收购数据
    async getGovBuy() {
        try {
            return await this.aiDao.getGovBuy();
        } catch (error) {
            console.error('获取政府收购数据失败:', error);
            return "获取政府收购数据失败";
        }
    }

    // 获取政府出售数据
    async getGovSell() {
        try {
            return await this.aiDao.getGovSell();
        } catch (error) {
            console.error('获取政府出售数据失败:', error);
            return "获取政府出售数据失败";
        }
    }

    // 获取经销商收购数据
    async dealerBuy() {
        try {
            return await this.aiDao.dealerBuy();
        } catch (error) {
            console.error('获取经销商收购数据失败:', error);
            return "获取经销商收购数据失败";
        }
    }

    // 获取农户出售数据
    async farmerSell() {
        try {
            return await this.aiDao.farmerSell();
        } catch (error) {
            console.error('获取农户出售数据失败:', error);
            return "获取农户出售数据失败";
        }
    }

    async getMyOrders(user_id){
        try {
            return await this.aiDao.getMyOrders(user_id);
        } catch (error) {
            console.error('获取农户出售数据失败:', error);
            return "获取农户出售数据失败";
        }
    }

    
    // 普通DeepSeek API代理接口
    /*
    async chatWithAI(req, res) {
        try {
            const { question } = req.body;
            
            // 调用DeepSeek API
            const response = await axios.post(
                'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions',
                {
                    model: 'deepseek-v3',
                    messages: [
                        { role: 'user', content: question }
                    ]
                },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer sk-893ad79db95a4414ade4fd5f6e6605fa' // API密钥
                    }
                }
            );
            
            // 将DeepSeek的响应转发给前端
            res.json(response.data);
        } catch (error) {
            console.error('调用DeepSeek API出错:', error.response?.data || error.message);
            res.status(500).json({ 
                error: '服务器错误', 
                message: error.response?.data?.error?.message || error.message 
            });
        }
    }
    */
}

module.exports = AIController;